From 9925f4a7dcd70737634456f88096025445e15b4c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 23 Feb 2006 18:27:18 +0100 Subject: [PATCH] Remove explicit munging of selector RPLs from Xen Linux x86/64. Not needed now it's done by Xen. Signed-off-by: Keir Fraser --- .../arch/x86_64/ia32/syscall32-xen.c | 2 +- .../arch/x86_64/kernel/entry-xen.S | 2 +- .../arch/x86_64/kernel/head-xen.S | 7 +-- .../arch/x86_64/kernel/traps-xen.c | 38 ++++++++-------- .../drivers/xen/core/smpboot.c | 2 +- .../include/asm-x86_64/mach-xen/asm/segment.h | 44 ------------------- xen/arch/x86/x86_32/mm.c | 4 +- xen/arch/x86/x86_64/mm.c | 9 ++-- 8 files changed, 32 insertions(+), 76 deletions(-) delete mode 100644 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/segment.h diff --git a/linux-2.6-xen-sparse/arch/x86_64/ia32/syscall32-xen.c b/linux-2.6-xen-sparse/arch/x86_64/ia32/syscall32-xen.c index 36186b1a83..e99a6f7585 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/ia32/syscall32-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/ia32/syscall32-xen.c @@ -119,7 +119,7 @@ void syscall32_cpu_init(void) /* Load these always in case some future AMD CPU supports SYSENTER from compat mode too. */ - checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)(__KERNEL_CS | 3)); + checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S index a010a17bb5..0ef077d66e 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S @@ -325,7 +325,7 @@ ENTRY(int_ret_from_sys_call) testb $3,CS-ARGOFFSET(%rsp) jnz 1f /* Need to set the proper %ss (not NULL) for ring 3 iretq */ - movl $__KERNEL_DS,SS-ARGOFFSET(%rsp) + movl $__KERNEL_DS|3,SS-ARGOFFSET(%rsp) jmp retint_restore_args # retrun from ring3 kernel 1: movl $_TIF_ALLWORK_MASK,%edi diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S index 8112691bf8..1f3e07bfb0 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S @@ -111,12 +111,12 @@ gdt: ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0 /* unused */ - .quad 0x00affa000000ffff /* __KERNEL_CS */ - .quad 0x00cff2000000ffff /* __KERNEL_DS */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ .quad 0x00cffa000000ffff /* __USER32_CS */ .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */ .quad 0x00affa000000ffff /* __USER_CS */ - .quad 0x00cffa000000ffff /* __KERNEL32_CS */ + .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ .quad 0,0 /* TSS */ .quad 0,0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ @@ -151,5 +151,6 @@ gdt_end: .ascii ",FEATURES=writable_page_tables" .ascii "|writable_descriptor_tables" .ascii "|auto_translated_physmap" + .ascii "|supervisor_mode_kernel" .ascii ",LOADER=generic" .byte 0 diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c index bcd0f0627d..9fd0b94cb5 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/traps-xen.c @@ -952,28 +952,28 @@ asmlinkage void math_state_restore(void) * specify |4 in the second field. */ static trap_info_t trap_table[] = { - { 0, 0|4, (__KERNEL_CS|0x3), (unsigned long)divide_error }, - { 1, 0|4, (__KERNEL_CS|0x3), (unsigned long)debug }, - { 3, 3|4, (__KERNEL_CS|0x3), (unsigned long)int3 }, - { 4, 3|4, (__KERNEL_CS|0x3), (unsigned long)overflow }, - { 5, 0|4, (__KERNEL_CS|0x3), (unsigned long)bounds }, - { 6, 0|4, (__KERNEL_CS|0x3), (unsigned long)invalid_op }, - { 7, 0|4, (__KERNEL_CS|0x3), (unsigned long)device_not_available }, - { 9, 0|4, (__KERNEL_CS|0x3), (unsigned long)coprocessor_segment_overrun}, - { 10, 0|4, (__KERNEL_CS|0x3), (unsigned long)invalid_TSS }, - { 11, 0|4, (__KERNEL_CS|0x3), (unsigned long)segment_not_present }, - { 12, 0|4, (__KERNEL_CS|0x3), (unsigned long)stack_segment }, - { 13, 0|4, (__KERNEL_CS|0x3), (unsigned long)general_protection }, - { 14, 0|4, (__KERNEL_CS|0x3), (unsigned long)page_fault }, - { 15, 0|4, (__KERNEL_CS|0x3), (unsigned long)spurious_interrupt_bug }, - { 16, 0|4, (__KERNEL_CS|0x3), (unsigned long)coprocessor_error }, - { 17, 0|4, (__KERNEL_CS|0x3), (unsigned long)alignment_check }, + { 0, 0|4, __KERNEL_CS, (unsigned long)divide_error }, + { 1, 0|4, __KERNEL_CS, (unsigned long)debug }, + { 3, 3|4, __KERNEL_CS, (unsigned long)int3 }, + { 4, 3|4, __KERNEL_CS, (unsigned long)overflow }, + { 5, 0|4, __KERNEL_CS, (unsigned long)bounds }, + { 6, 0|4, __KERNEL_CS, (unsigned long)invalid_op }, + { 7, 0|4, __KERNEL_CS, (unsigned long)device_not_available }, + { 9, 0|4, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun}, + { 10, 0|4, __KERNEL_CS, (unsigned long)invalid_TSS }, + { 11, 0|4, __KERNEL_CS, (unsigned long)segment_not_present }, + { 12, 0|4, __KERNEL_CS, (unsigned long)stack_segment }, + { 13, 0|4, __KERNEL_CS, (unsigned long)general_protection }, + { 14, 0|4, __KERNEL_CS, (unsigned long)page_fault }, + { 15, 0|4, __KERNEL_CS, (unsigned long)spurious_interrupt_bug }, + { 16, 0|4, __KERNEL_CS, (unsigned long)coprocessor_error }, + { 17, 0|4, __KERNEL_CS, (unsigned long)alignment_check }, #ifdef CONFIG_X86_MCE - { 18, 0|4, (__KERNEL_CS|0x3), (unsigned long)machine_check }, + { 18, 0|4, __KERNEL_CS, (unsigned long)machine_check }, #endif - { 19, 0|4, (__KERNEL_CS|0x3), (unsigned long)simd_coprocessor_error }, + { 19, 0|4, __KERNEL_CS, (unsigned long)simd_coprocessor_error }, #ifdef CONFIG_IA32_EMULATION - { IA32_SYSCALL_VECTOR, 3|4, (__KERNEL_CS|0x3), (unsigned long)ia32_syscall}, + { IA32_SYSCALL_VECTOR, 3|4, __KERNEL_CS, (unsigned long)ia32_syscall}, #endif { 0, 0, 0, 0 } }; diff --git a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c index 05f67a70e0..8f347c4ec6 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/smpboot.c @@ -188,7 +188,7 @@ void vcpu_prepare(int vcpu) ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; #else /* __x86_64__ */ - ctxt.user_regs.cs = __KERNEL_CS | 3; + ctxt.user_regs.cs = __KERNEL_CS; ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs); ctxt.kernel_ss = __KERNEL_DS; diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/segment.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/segment.h deleted file mode 100644 index 729a4d19a5..0000000000 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/segment.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _ASM_SEGMENT_H -#define _ASM_SEGMENT_H - -#include - -#define __KERNEL_CS 0x10 -#define __KERNEL_DS 0x1b - -#define __KERNEL32_CS 0x3b - -/* - * we cannot use the same code segment descriptor for user and kernel - * -- not even in the long flat mode, because of different DPL /kkeil - * The segment offset needs to contain a RPL. Grr. -AK - * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) - */ - -#define __USER32_CS 0x23 /* 4*8+3 */ -#define __USER_DS 0x2b /* 5*8+3 */ -#define __USER_CS 0x33 /* 6*8+3 */ -#define __USER32_DS __USER_DS - -#define GDT_ENTRY_TLS 1 -#define GDT_ENTRY_TSS 8 /* needs two entries */ -#define GDT_ENTRY_LDT 10 /* needs two entries */ -#define GDT_ENTRY_TLS_MIN 12 -#define GDT_ENTRY_TLS_MAX 14 -/* 15 free */ - -#define GDT_ENTRY_TLS_ENTRIES 3 - -/* TLS indexes for 64bit - hardcoded in arch_prctl */ -#define FS_TLS 0 -#define GS_TLS 1 - -#define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3) -#define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) - -#define IDT_ENTRIES 256 -#define GDT_ENTRIES 16 -#define GDT_SIZE (GDT_ENTRIES * 8) -#define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) - -#endif diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index f622498922..d279204486 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -250,8 +250,8 @@ int check_descriptor(struct desc_struct *d) * gates (consider a call gate pointing at another kernel descriptor with * DPL 0 -- this would get the OS ring-0 privileges). */ - if ( (b & _SEGMENT_DPL) == 0 ) - d->b = b = b | (0x01<<13); /* Force DPL == 1 */ + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); if ( !(b & _SEGMENT_S) ) { diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index ee45c2a875..4770a0436a 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -228,8 +228,7 @@ long subarch_memory_op(int op, void *arg) long do_stack_switch(unsigned long ss, unsigned long esp) { - if ( (ss & 3) != 3 ) - return -EPERM; + fixup_guest_selector(ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; return 0; @@ -298,9 +297,9 @@ int check_descriptor(struct desc_struct *d) if ( !(b & _SEGMENT_P) ) goto good; - /* The guest can only safely be executed in ring 3. */ - if ( (b & _SEGMENT_DPL) != _SEGMENT_DPL ) - goto bad; + /* Check and fix up the DPL. */ + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) -- 2.30.2